
from rest_framework.decorators import api_view
from rest_framework.response import Response
from django.http import JsonResponse
from django.core.cache import cache
from monitoring.models import ZabbixServer
from monitoring.utils.zabbix_api import ZabbixAPIManager
import json
import time
from datetime import datetime, timedelta
from concurrent.futures import ThreadPoolExecutor, as_completed
import logging

logger = logging.getLogger(__name__)


@api_view(['GET'])
def get_dashboard_data(request):
    """获取仪表盘数据"""
    try:
        # 获取参数
        host_group = request.GET.get('hostgroup', '')
        host_name = request.GET.get('host', '')
        item_name = request.GET.get('item', '')

        zabbix_server = ZabbixServer.objects.filter(is_active=True).first()
        if not zabbix_server:
            return Response({'error': '没有活跃的Zabbix服务器'}, status=400)

        zabbix_api = ZabbixAPIManager(zabbix_server)
        if not zabbix_api._connect():
            return Response({'error': '连接Zabbix失败'}, status=500)

        result = {}

        # 获取主机组列表
        groups = zabbix_api.zapi.hostgroup.get(
            output=['groupid', 'name'],
            real_hosts=True
        )
        result['hostgroups'] = [{'id': g['groupid'], 'name': g['name']} for g in groups]

        # 如果选择了主机组，获取主机列表
        if host_group:
            hosts = zabbix_api.zapi.host.get(
                output=['hostid', 'host', 'name', 'status'],
                groupids=[host_group] if host_group.isdigit() else None,
                filter={'name': host_group} if not host_group.isdigit() else None
            )
            result['hosts'] = [{'id': h['hostid'], 'host': h['host'], 'name': h['name'], 'status': h['status']} for h in hosts]

        # 如果选择了主机，获取监控项列表
        if host_name:
            host_filter = {'host': host_name} if not host_name.isdigit() else {'hostid': host_name}
            hosts = zabbix_api.zapi.host.get(
                output=['hostid'],
                filter=host_filter
            )

            if hosts:
                host_id = hosts[0]['hostid']
                items = zabbix_api.zapi.item.get(
                    hostids=[host_id],
                    output=['itemid', 'name', 'key_', 'value_type', 'units', 'lastvalue', 'lastclock'],
                    filter={'status': 0},
                    sortfield='name'
                )
                result['items'] = []
                for item in items:
                    result['items'].append({
                        'id': item['itemid'],
                        'name': item['name'],
                        'key': item['key_'],
                        'value_type': item['value_type'],
                        'units': item.get('units', ''),
                        'lastvalue': item.get('lastvalue', ''),
                        'lastclock': item.get('lastclock', '')
                    })

        # 如果选择了具体监控项，获取历史数据
        if item_name:
            # 获取最近6小时的历史数据
            time_from = int((datetime.now() - timedelta(hours=6)).timestamp())
            time_till = int(datetime.now().timestamp())

            item_filter = {'name': item_name} if not item_name.isdigit() else {'itemid': item_name}
            items = zabbix_api.zapi.item.get(
                output=['itemid', 'value_type'],
                filter=item_filter
            )

            if items:
                item_id = items[0]['itemid']
                value_type = int(items[0]['value_type'])

                # 根据数据类型选择历史表
                if value_type in [0, 3]:  # 数值类型
                    history = zabbix_api.zapi.history.get(
                        itemids=[item_id],
                        time_from=time_from,
                        time_till=time_till,
                        output='extend',
                        sortfield='clock',
                        limit=1000
                    )
                else:  # 其他类型
                    history = []

                result['history'] = []
                for h in history:
                    result['history'].append({
                        'clock': int(h['clock']),
                        'value': float(h['value']) if h['value'].replace('.', '').replace('-', '').isdigit() else h['value'],
                        'timestamp': datetime.fromtimestamp(int(h['clock'])).strftime('%Y-%m-%d %H:%M:%S')
                    })

        # 如果没有选择监控项，获取主机概览数据
        elif host_name and not item_name:
            host_filter = {'host': host_name} if not host_name.isdigit() else {'hostid': host_name}
            hosts = zabbix_api.zapi.host.get(
                output=['hostid', 'host', 'name'],
                filter=host_filter
            )

            if hosts:
                host_id = hosts[0]['hostid']

                # 获取关键监控项的最新值
                key_items = [
                    'CPU idle time',
                    'Memory utilization',
                    'Space utilization',
                    'Load average (1m avg)',
                    'Available memory',
                    'System uptime'
                ]

                overview_data = {}
                for key_item in key_items:
                    items = zabbix_api.zapi.item.get(
                        hostids=[host_id],
                        output=['itemid', 'name', 'key_', 'lastvalue', 'units'],
                        search={'name': key_item},
                        filter={'status': 0},
                        limit=1
                    )

                    if items:
                        item = items[0]
                        value = item.get('lastvalue', '')
                        if value and value.replace('.', '').replace('-', '').isdigit():
                            value = float(value)
                            # CPU使用率需要转换
                            if 'CPU idle time' in item['name']:
                                value = 100 - value
                                overview_data['cpu_usage'] = round(value, 2)
                            elif 'Memory utilization' in item['name']:
                                overview_data['memory_usage'] = round(value, 2)
                            elif 'Space utilization' in item['name']:
                                overview_data['disk_usage'] = round(value, 2)
                            elif 'Load average' in item['name']:
                                overview_data['load_avg'] = round(value, 3)
                            elif 'Available memory' in item['name']:
                                overview_data['available_memory'] = int(value)
                            elif 'System uptime' in item['name']:
                                overview_data['uptime'] = int(value)

                result['overview'] = overview_data

        return Response(result)

    except Exception as e:
        return Response({'error': str(e)}, status=500)


@api_view(['GET'])
def get_host_overview(request):
    """获取所有主机概览"""
    try:
        zabbix_server = ZabbixServer.objects.filter(is_active=True).first()
        if not zabbix_server:
            return Response({'error': '没有活跃的Zabbix服务器'}, status=400)

        zabbix_api = ZabbixAPIManager(zabbix_server)
        if not zabbix_api._connect():
            return Response({'error': '连接Zabbix失败'}, status=500)

        # 获取所有主机
        hosts = zabbix_api.zapi.host.get(
            output=['hostid', 'host', 'name', 'status'],
            selectGroups=['name']
        )

        result = []
        for host in hosts:
            host_data = {
                'hostid': host['hostid'],
                'host': host['host'],
                'name': host['name'],
                'status': '在线' if host['status'] == '0' else '离线',
                'groups': [g['name'] for g in host.get('groups', [])],
                'metrics': {}
            }

            # 获取关键指标
            if host['status'] == '0':  # 只获取在线主机的数据
                try:
                    # CPU使用率
                    cpu_items = zabbix_api.zapi.item.get(
                        hostids=[host['hostid']],
                        search={'name': 'CPU idle time'},
                        output=['lastvalue'],
                        filter={'status': 0},
                        limit=1
                    )
                    if cpu_items and cpu_items[0].get('lastvalue'):
                        cpu_idle = float(cpu_items[0]['lastvalue'])
                        host_data['metrics']['cpu_usage'] = round(100 - cpu_idle, 2)

                    # 内存使用率
                    mem_items = zabbix_api.zapi.item.get(
                        hostids=[host['hostid']],
                        search={'name': 'Memory utilization'},
                        output=['lastvalue'],
                        filter={'status': 0},
                        limit=1
                    )
                    if mem_items and mem_items[0].get('lastvalue'):
                        host_data['metrics']['memory_usage'] = round(float(mem_items[0]['lastvalue']), 2)

                    # 磁盘使用率
                    disk_items = zabbix_api.zapi.item.get(
                        hostids=[host['hostid']],
                        search={'name': 'Space utilization'},
                        output=['lastvalue'],
                        filter={'status': 0},
                        limit=1
                    )
                    if disk_items and disk_items[0].get('lastvalue'):
                        host_data['metrics']['disk_usage'] = round(float(disk_items[0]['lastvalue']), 2)

                except:
                    pass  # 忽略单个主机的错误

            result.append(host_data)

        return Response(result)

    except Exception as e:
        logger.error(f"获取仪表盘数据失败: {str(e)}")
        return Response({'error': str(e)}, status=500)


@api_view(['GET'])
def get_host_groups(request):
    """获取主机组列表"""
    try:
        # 使用缓存，5分钟过期
        cache_key = 'zabbix_host_groups'
        cached_data = cache.get(cache_key)
        if cached_data:
            return Response({'success': True, 'data': cached_data})

        zabbix_server = ZabbixServer.objects.filter(is_active=True).first()
        if not zabbix_server:
            return Response({'success': False, 'message': '没有活跃的Zabbix服务器'}, status=400)

        zabbix_api = ZabbixAPIManager(zabbix_server)
        if not zabbix_api._connect():
            return Response({'success': False, 'message': '连接Zabbix失败'}, status=500)

        groups = zabbix_api.zapi.hostgroup.get(
            output=['groupid', 'name'],
            real_hosts=True,
            sortfield='name'
        )

        result = [{'id': g['groupid'], 'name': g['name']} for g in groups]

        # 缓存5分钟
        cache.set(cache_key, result, 300)

        return Response({'success': True, 'data': result})

    except Exception as e:
        logger.error(f"获取主机组失败: {str(e)}")
        return Response({'success': False, 'message': str(e)}, status=500)


@api_view(['GET'])
def get_hosts_by_group(request, group_id):
    """根据主机组获取主机列表"""
    try:
        cache_key = f'zabbix_hosts_group_{group_id}'
        cached_data = cache.get(cache_key)
        if cached_data:
            return Response({'success': True, 'data': cached_data})

        zabbix_server = ZabbixServer.objects.filter(is_active=True).first()
        if not zabbix_server:
            return Response({'success': False, 'message': '没有活跃的Zabbix服务器'}, status=400)

        zabbix_api = ZabbixAPIManager(zabbix_server)
        if not zabbix_api._connect():
            return Response({'success': False, 'message': '连接Zabbix失败'}, status=500)

        hosts = zabbix_api.zapi.host.get(
            output=['hostid', 'host', 'name', 'status'],
            groupids=[group_id],
            sortfield='name'
        )

        result = []
        for h in hosts:
            status_map = {'0': 'Online', '1': 'Offline', '2': 'Unknown'}
            result.append({
                'id': h['hostid'],
                'host': h['host'],
                'name': h['name'],
                'status': status_map.get(h['status'], 'Unknown')
            })

        # 缓存3分钟
        cache.set(cache_key, result, 180)

        return Response({'success': True, 'data': result})

    except Exception as e:
        logger.error(f"获取主机列表失败: {str(e)}")
        return Response({'success': False, 'message': str(e)}, status=500)


@api_view(['GET'])
def get_host_latest_data(request, host_id):
    """获取主机最新数据"""
    try:
        cache_key = f'zabbix_host_data_{host_id}'
        cached_data = cache.get(cache_key)
        if cached_data:
            return Response({'success': True, 'data': cached_data})

        zabbix_server = ZabbixServer.objects.filter(is_active=True).first()
        if not zabbix_server:
            return Response({'success': False, 'message': '没有活跃的Zabbix服务器'}, status=400)

        zabbix_api = ZabbixAPIManager(zabbix_server)
        if not zabbix_api._connect():
            return Response({'success': False, 'message': '连接Zabbix失败'}, status=500)

        # 获取主机状态
        host_info = zabbix_api.zapi.host.get(
            output=['hostid', 'host', 'name', 'status'],
            hostids=[host_id]
        )

        if not host_info:
            return Response({'success': False, 'message': '主机不存在'}, status=404)

        host = host_info[0]
        result = {
            'status': 'Online' if host['status'] == '0' else 'Offline',
            'cpu_usage': 0,
            'memory_usage': 0,
            'disk_usage': 0,
            'network_speed': 0,
            'system_load': 0,
            'process_count': 0
        }

        # 获取关键监控项的最新数据
        items = zabbix_api.zapi.item.get(
            output=['itemid', 'key_', 'lastvalue', 'units'],
            hostids=[host_id],
            search={'key_': ['cpu', 'memory', 'disk', 'net', 'load', 'proc']},
            searchWildcardsEnabled=True,
            limit=50
        )

        for item in items:
            key = item['key_'].lower()
            try:
                value = float(item['lastvalue'])

                if 'cpu' in key and 'util' in key:
                    result['cpu_usage'] = max(result['cpu_usage'], value)
                elif 'memory' in key and ('util' in key or 'pused' in key):
                    result['memory_usage'] = max(result['memory_usage'], value)
                elif 'disk' in key and ('util' in key or 'pused' in key):
                    result['disk_usage'] = max(result['disk_usage'], value)
                elif 'net' in key and 'in' in key:
                    result['network_speed'] = max(result['network_speed'], value)
                elif 'load' in key and 'avg1' in key:
                    result['system_load'] = value
                elif 'proc' in key and 'num' in key:
                    result['process_count'] = int(value)
            except (ValueError, TypeError):
                continue

        # 缓存1分钟
        cache.set(cache_key, result, 60)

        return Response({'success': True, 'data': result})

    except Exception as e:
        logger.error(f"获取主机数据失败: {str(e)}")
        return Response({'success': False, 'message': str(e)}, status=500)


@api_view(['GET'])
def get_host_graphs(request, host_id):
    """获取主机图表配置"""
    try:
        cache_key = f'zabbix_host_graphs_{host_id}'
        cached_data = cache.get(cache_key)
        if cached_data:
            return Response({'success': True, 'data': cached_data})

        zabbix_server = ZabbixServer.objects.filter(is_active=True).first()
        if not zabbix_server:
            return Response({'success': False, 'message': '没有活跃的Zabbix服务器'}, status=400)

        zabbix_api = ZabbixAPIManager(zabbix_server)
        if not zabbix_api._connect():
            return Response({'success': False, 'message': '连接Zabbix失败'}, status=500)

        # 获取主机的监控项，用于生成图表
        items = zabbix_api.zapi.item.get(
            output=['itemid', 'key_', 'name', 'units', 'value_type'],
            hostids=[host_id],
            monitored=True,
            limit=20,
            sortfield='name'
        )

        result = []
        chart_id = 1

        for item in items:
            # 根据监控项类型决定图表类型
            chart_type = 'line'  # 默认折线图

            key = item['key_'].lower()
            if any(keyword in key for keyword in ['cpu', 'memory', 'disk']) and 'util' in key:
                chart_type = 'gauge'  # 使用率用仪表盘
            elif 'proc' in key or 'count' in key:
                chart_type = 'bar'  # 计数用柱状图

            result.append({
                'id': f"{host_id}_{item['itemid']}",
                'graphid': f"{host_id}_{item['itemid']}",
                'name': item['name'],
                'itemId': item['itemid'],
                'type': chart_type,
                'unit': item.get('units', ''),
                'items': [{
                    'itemid': item['itemid'],
                    'key_': item['key_'],
                    'units': item.get('units', '')
                }]
            })
            chart_id += 1

        # 缓存10分钟
        cache.set(cache_key, result, 600)

        return Response({'success': True, 'data': result})

    except Exception as e:
        logger.error(f"获取主机图表失败: {str(e)}")
        return Response({'success': False, 'message': str(e)}, status=500)


@api_view(['GET'])
def get_item_history(request):
    """获取监控项历史数据"""
    try:
        itemid = request.GET.get('itemid')
        time_from = request.GET.get('time_from', 'now-1h')
        limit = int(request.GET.get('limit', 100))

        if not itemid:
            return Response({'success': False, 'message': '缺少itemid参数'}, status=400)

        # 简单的缓存key
        cache_key = f'zabbix_item_history_{itemid}_{time_from}_{limit}'
        cached_data = cache.get(cache_key)
        if cached_data:
            return Response({'success': True, 'data': cached_data})

        zabbix_server = ZabbixServer.objects.filter(is_active=True).first()
        if not zabbix_server:
            return Response({'success': False, 'message': '没有活跃的Zabbix服务器'}, status=400)

        zabbix_api = ZabbixAPIManager(zabbix_server)
        if not zabbix_api._connect():
            return Response({'success': False, 'message': '连接Zabbix失败'}, status=500)

        # 计算时间范围
        now = int(time.time())
        if time_from == 'now-1h':
            time_till = now
            time_from_ts = now - 3600
        elif time_from == 'now-6h':
            time_till = now
            time_from_ts = now - 21600
        else:
            time_till = now
            time_from_ts = now - 3600

        # 获取历史数据
        history = zabbix_api.zapi.history.get(
            output='extend',
            itemids=[itemid],
            time_from=time_from_ts,
            time_till=time_till,
            sortfield='clock',
            sortorder='ASC',
            limit=limit
        )

        result = []
        for h in history:
            result.append({
                'clock': int(h['clock']),
                'value': float(h['value']) if h['value'].replace('.', '').replace('-', '').isdigit() else 0
            })

        # 缓存30秒
        cache.set(cache_key, result, 30)

        return Response({'success': True, 'data': result})

    except Exception as e:
        logger.error(f"获取历史数据失败: {str(e)}")
        return Response({'success': False, 'message': str(e)}, status=500)
